#ifndef ASFINGER_PBRPC_CORE_STRUCT_INTERFACE_H_
#define ASFINGER_PBRPC_CORE_STRUCT_INTERFACE_H_

#include <memory>
#include <string>
#include <vector>

#include "core/config.h"

namespace asfinger {
namespace pbrpc {

/*!
 * 源文件的注释基类
 */
struct CommentBase {
  virtual ~CommentBase() {}
  /*!
   * 获取前导注释
   * @param prefix 前缀
   * @return 前导注释
   */
  virtual std::string GetLeadingComments(const std::string prefix) const = 0;

  /*!
   * 获取尾部注释
   * @param prefix 前缀
   * @return 尾部注释
   */
  virtual std::string GetTrailingComments(const std::string prefix) const = 0;
};

/*!
 * 方法抽象接口
 */
struct MethodInterface
    : public CommentBase {
  virtual ~MethodInterface() {}

  /*!
   * 获取方法名
   * @return 方法名
   */
  virtual std::string GetName() const = 0;

  /*!
   * 设置输入类型类名称
   * @return 输入类型类名称
   */
  virtual std::string GetInputTypeClassName() const = 0;

  /*!
   * 设置输出类型类名称
   * @return 输出类型类名称
   */
  virtual std::string GetOutputTypeClassName() const = 0;

  /*!
   * 获取输入类型文件名称
   * @return 输入类型名称
   */
  virtual std::string GetInputTypeFileName() const = 0;

  /*!
   * 获取输出类型文件名称
   * @return 输出类型名称
   */
  virtual std::string GetOutputTypeFileName() const = 0;

  /*!
   * 非缓冲流
   * @return true 非缓冲流
   * @return false 缓冲流
   */
  virtual bool IsNoStreaming() const = 0;

  /*!
   * 客户端缓冲流
   * @return true 客户端缓冲流
   * @return false 非客户端缓冲流
   */
  virtual bool IsClientStreaming() const = 0;

  /*!
   * 服务器缓冲流
   * @return true 服务器缓冲流
   * @return false 非服务器缓冲流
   */
  virtual bool IsServerStreaming() const = 0;

  /*!
   * 双向缓冲流
   * @return true 双向缓冲流
   * @return false 非双向缓冲流
   */
  virtual bool IsBidiStreaming() const = 0;
};

/*!
 * 服务抽象接口
 */
struct ServiceInterface
    : public CommentBase {
  virtual ~ServiceInterface() {}

  /*!
   * 获取服务名
   * @return 服务名
   */
  virtual std::string GetName() const = 0;

  /*!
   * 获取方法数量
   * @return 方法数量
   */
  virtual int GetMethodCount() const = 0;

  /*!
   * 获取方法
   * @param index 函数位置
   * @return 方法
   */
  virtual std::unique_ptr<const MethodInterface> GetMethodByIndex(int index) const = 0;
};

/*!
 * 辅助打印器
 */
struct Printer {
  virtual ~Printer() {}

  /*!
   *
   * @param vars
   * @param template_string
   */
  virtual void Print(const std::map<std::string, std::string> &vars,
                     const char *template_string) = 0;

  /*!
   *
   * @param str
   */
  virtual void Print(const char *str) = 0;

  /*!
   *
   * @param str
   */
  virtual void PrintRaw(const char *str) = 0;

  /*!
   * 缩进
   */
  virtual void Indent() = 0;

  /*!
   * 突出
   */
  virtual void Outdent() = 0;

};

/*!
 * 文件抽象接口
 */
struct FileInterface
    : public CommentBase {
  virtual ~FileInterface() {}

  /*!
   * 获取文件名
   * @return 文件名
   */
  virtual std::string GetFileName() const = 0;

  /*!
   * 获取文件名不带扩展
   * @return 文件名不带扩展
   */
  virtual std::string GetFileNameWithoutExt() const = 0;

  /*!
   * 获取包名
   * @return 包名
   */
  virtual std::string GetPackage() const = 0;

  /*!
   * 获取包名部分
   * @return 包名部分
   */
  virtual std::vector<std::string> GetPackageParts() const = 0;

  /*!
   *
   * @return
   */
  virtual std::string AdditionalHeaders() const = 0;

  /*!
   * 获取服务数量
   * @return 服务数量
   */
  virtual int GetServiceCount() const = 0;

  /*!
   * 获取服务器
   * @param i
   * @return 服务器
   */
  virtual std::unique_ptr<const ServiceInterface> GetServiceByIndex(int index) const = 0;

  /*!
   * 创建打印器
   * @param str
   * @return 打印器
   */
  virtual std::unique_ptr<Printer> CreatePrinter(std::string &str) const = 0;
};

} //! namespace pbrpc
} //! namespace asfinger

#endif //ASFINGER_PBRPC_CORE_STRUCT_INTERFACE_H_